#include "formatmanager.h"
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>

using namespace std;

map<QString, Format *> FormatManager::formats_;
map<QString, Format *> FormatManager::suffixes_;

int FormatManager::load(){
    QFile file("manifest.xml");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Failed to open XML file.";
        return -1;
    }

    QXmlStreamReader xmlReader(&file);

    QString name;
    QString implement;
    QStringList suffix;
    map<QString, QString> subs;

    bool in_format = false;

    while (!xmlReader.atEnd() && !xmlReader.hasError()) {
        xmlReader.readNext();

        if (xmlReader.isStartElement()) {
            if(!in_format && xmlReader.name().toString() == "format") {
                in_format = true;
                name.clear();
                implement.clear();
                suffix.clear();
                subs.clear();
                if (xmlReader.attributes().hasAttribute("name"))
                    name = xmlReader.attributes().value("name").toString();
            } else if (in_format) {
                if (xmlReader.name().toString() == "implement") {
                    implement = xmlReader.readElementText();
                } else if (xmlReader.name().toString() == "suffix"){
                    suffix = xmlReader.readElementText().split(",");
                } else if (xmlReader.name().toString() == "sub-format"){
                    if (xmlReader.attributes().hasAttribute("pattern")) {
                        auto pattern = xmlReader.attributes().value("pattern").toString();
                        subs[pattern] = xmlReader.readElementText();
                    }
                }
            }
        } else if (xmlReader.isEndElement()) {
            if(in_format && xmlReader.name().toString() == "format") {
                in_format = false;
                if (!name.isEmpty()) {
                    map<QString, Format *> sub_formats;
                    for_each(subs.begin(),
                             subs.end(),
                             [&](pair<QString, QString> obj){
                                 auto it = formats_.find(obj.second);
                                 if(it != formats_.end()) sub_formats[obj.first] = it->second;
                             });

                    auto format = new Format(name, implement, sub_formats);
                    formats_[name] = format;

                    for_each(suffix.begin(),
                             suffix.end(),
                             [&](QString obj){
                                 suffixes_[obj] = format;
                             });
                }
            }
        }
    }

    if (xmlReader.hasError()) {
        qDebug() << "XML error:" << xmlReader.errorString();
        return -1;
    }

    qDebug() << "Parsing completed.";

    return 0;
}

Format *FormatManager::getFormatForSuffix(QString suffix){
    auto it = suffixes_.find(suffix);
    if(it != suffixes_.end()) return it->second;
    return nullptr;
}

Format *FormatManager::getFormatForName(QString name)
{
    auto it = formats_.find(name);
    if(it != formats_.end()) return it->second;
    return nullptr;
}
